import { createNitro, createDevServer, prepare, build } from "nitropack";
import getPort from "get-port";
const hmrKeyRe = /^runtimeConfig\.|routeRules\./;
import chalk from "chalk";

export const viteNitroMockPlugin = ({
  mockServerPackage = "nitro-app",
  port = 5320,
  verbose = true,
} = {}) => {
  return {
    async configureServer(server) {
      console.log("🚀 [viteNitroMockPlugin] 开始配置 Mock 服务器...");

      const availablePort = await getPort({ port });
      if (availablePort !== port) {
        console.warn(`端口 ${port} 不可用，跳过 Mock 服务器启动`);
        return;
      }

      const pkg = "C:/Users/Administrator/Desktop/666/dome/nitro-app";
      if (!pkg) {
        console.warn(
          `Package ${mockServerPackage} not found. Skip mock server.`
        );
        return;
      }

      console.log(`📦 找到 Mock 包: ${pkg}`);

      // 添加错误处理的异步调用
      runNitroServer(pkg, port, verbose).catch((error) => {
        console.error("❌ Nitro Mock 服务器启动失败:", error);
      });

      const _printUrls = server.printUrls;
      server.printUrls = () => {
        _printUrls();

        console.log(
          `  ${chalk.green("➜")}  ${chalk.bold(
            "后端 Mock 服务"
          )}:  http://localhost:${port}/api`
        );
      };
    },
    enforce: "pre",
    name: "vite:mock-server",
  };
};

async function runNitroServer(rootDir: string, port: number, verbose: boolean) {
  console.log("🔧 [runNitroServer] 开始启动 Nitro 服务器...");
  console.log("📂 rootDir:", rootDir);
  console.log("🔌 port:", port);
  console.log("🔊 verbose:", verbose);

  let nitro: any;
  const reload = async () => {
    try {
      if (nitro) {
        console.info("🔄 重启开发服务器...");
        if ("unwatch" in nitro.options._c12) {
          await nitro.options._c12.unwatch();
        }
        await nitro.close();
      }

      console.log("⚙️ 创建 Nitro 实例...");
      nitro = await createNitro(
        {
          dev: true,
          preset: "nitro-dev",
          rootDir,
        },
        {
          c12: {
            async onUpdate({ getDiff, newConfig }) {
              const diff = getDiff(); // 🔍 获取配置文件的变更差异
              // 🚫 没有变更就跳过
              if (diff.length === 0) {
                return;
              }
              // 🔊 如果开启了 verbose 模式，打印变更信息
              verbose &&
                console.info(
                  `Nitro config updated:\n${diff
                    .map((entry) => `  ${entry.toString()}`)
                    .join("\n")}`
                );
              // 🤔 根据变更类型决定处理方式
              await (diff.every((e) => hmrKeyRe.test(e.key))
                ? nitro.updateConfig(newConfig.config) // ⚡ 热更新（轻量）
                : reload()); // 🔄 完全重启（重量）
            },
          },
          watch: true,
        }
      );

      console.log("🎣 注册重启钩子...");
      nitro.hooks.hookOnce("restart", reload);

      console.log("🌐 创建开发服务器...");
      const server = createDevServer(nitro);

      console.log(`🚀 监听端口 ${port}...`);
      await server.listen(port, { showURL: false });

      console.log("🔧 准备 Nitro...");
      await prepare(nitro);

      console.log("🏗️ 构建 Nitro...");
      await build(nitro);

      if (verbose) {
        console.log("");
        console.log("✅ Nitro Mock Server started successfully!");
        console.info(`🔗 Mock API 可用地址: http://localhost:${port}/api`);
      }
    } catch (error) {
      console.error("❌ [runNitroServer] 启动失败:", error);
      throw error;
    }
  };

  return await reload();
}
